/*
 * $Id: GeodataController.java 43 2013-04-19 15:16:56Z gabakyan $
 * $Author: gabakyan $
 * $Revision: 43 $
 * $Date: 2013-04-19 15:16:56 +0000 (Fri, 19 Apr 2013) $
 *
 * Copyright (c) 2013 Supply Chain Intelligence (SCI), Inc.
 * http://www.scintelligence.com/, Email: info@scintelligence.com
 * All rights reserved.
 *
 * This file is part of Logistics Map.
 *
 * Logistics Map is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 *
 * Logistics Map is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Logistics Map.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.sci.logisticsmap.web.controller;

import com.sci.logisticsmap.service.GeodataService;
import com.sci.logisticsmap.service.model.*;
import com.sci.logisticsmap.service.model.UpdateGeodataLocationsRequest;
import com.sci.logisticsmap.service.model.UpdateGeodataLocationRequest;
import com.sci.logisticsmap.service.model.GeodataResponse;
import com.sci.logisticsmap.support.model.ResponseWrapper;
import com.sci.logisticsmap.web.security.support.SecurityContextHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;

/**
 * The Controller for processing Geodata view/ajax requests.
 *
 * @author gabakyan@gmail.com (Last modified by $Author: gabakyan $)
 * @version $Revision: 43 $
 */
@Controller
@RequestMapping("")
public class GeodataController extends BaseController {
    /**
     * The "get-geodata" ajax path.
     */
    public static final String PATH_AJAX_GET_GEODATA = "/ajax/get-geodata";
    /**
     * The "get-geodata-response" ajax path.
     */
    public static final String PATH_AJAX_GET_GEODATA_RESPONSE = "/ajax/get-geodata-response";
    /**
     * The "list-geodata" ajax path.
     */
    public static final String PATH_AJAX_LIST_GEODATA = "/ajax/list-geodata";
    /**
     * The "get-geodata-location" ajax path.
     */
    public static final String PATH_AJAX_GET_GEODATA_LOCATION = "/ajax/get-geodata-location";
    /**
     * The "update-geodata-location" ajax path.
     */
    public static final String PATH_AJAX_UPDATE_GEODATA_LOCATION = "/ajax/update-geodata-location";
    /**
     * The "update-geodata-locations" ajax path.
     */
    public static final String PATH_AJAX_UPDATE_GEODATA_LOCATIONS = "/ajax/update-geodata-locations";
    /**
     * The "delete-geodata-location" ajax path.
     */
    public static final String PATH_AJAX_DELETE_GEODATA_LOCATION = "/ajax/delete-geodata-location";
    /**
     * The "restore-geodata-location" ajax path.
     * 2013-04-19, Don't Remove a Stop Forever
     * Allow user to 'enable' it (removed Stop) so then it reappears.
     */
    public static final String PATH_AJAX_RESTORE_GEODATA_LOCATION = "/ajax/restore-geodata-location";
//    /**
//     * The "list-not-geocoded-geodata-locations" ajax path.
//     */
//    public static final String PATH_AJAX_LIST_NOT_GEOCODED_GEODATA_LOCATIONS = "/ajax/list-not-geocoded-geodata-locations";
    /**
     * The "export-geodata" ajax path.
     */
    public static final String PATH_AJAX_EXPORT_GEODATA = "/ajax/export-geodata";

    /**
     * The Geodata service.
     */
    @Autowired
    private GeodataService geodataService;

    /**
     * The default constructor.
     * Initializes a Controller class.
     */
    public GeodataController() {
    }

    /*
     * (non-Javadoc)
     *
     * @see BaseController#init()
     */
    @PostConstruct
    public void init() {
        super.init();
    }

    /**
     * The method to response on the "get-geodata" ajax request.
     *
     * @param  id
     *         The Geodata id.
     * @param  request
     *         The http servlet request.
     * @param  session
     *         The http session.
     * @param  model
     *         The model.
     *
     * @return the wrapped Geodata model.
     */
    @RequestMapping(value=PATH_AJAX_GET_GEODATA, method={RequestMethod.GET})
    public @ResponseBody ResponseWrapper<GeodataDTModel> onAjaxGetGeodata(@RequestParam(value="id", required=true) String id,
                                                                       HttpServletRequest request, HttpSession session, Model model) {
        ResponseWrapper<GeodataDTModel> responseWrapper;
        try {
            //SessionUserDTModel sessionUser = SecurityContextHelper.getAuthenticatedUserDTModel();
            responseWrapper = geodataService.getDTModelResponse(id, session.getId());
            //responseWrapper = geodataService.getDTModelResponse(id, sessionUser.getUsername());
        } catch(Exception e) {
            responseWrapper = new ResponseWrapper<GeodataDTModel>();
            addExceptionToResponseWrapper(responseWrapper, e);
            logger.error("onAjaxGetGeodata", e);
		}

        return responseWrapper;
    }

    /**
     * The method to response on the "get-geodata-response" ajax request.
     *
     * @param  id
     *         The Geodata id.
     * @param  request
     *         The http servlet request.
     * @param  session
     *         The http session.
     * @param  model
     *         The model.
     *
     * @return the wrapped Geodata response.
     */
    @RequestMapping(value=PATH_AJAX_GET_GEODATA_RESPONSE, method={RequestMethod.GET})
    public @ResponseBody ResponseWrapper<GeodataResponse> onAjaxGetGeodataResponse(@RequestParam(value="id", required=true) String id,
                                                                                   HttpServletRequest request, HttpSession session, Model model) {
        ResponseWrapper<GeodataResponse> responseWrapper;
        try {
            //SessionUserDTModel sessionUser = SecurityContextHelper.getAuthenticatedUserDTModel();
            responseWrapper = geodataService.getGeodataResponse(id, session.getId());
            //responseWrapper = geodataService.getGeodataResponse(id, sessionUser.getUsername());
        } catch(Exception e) {
            responseWrapper = new ResponseWrapper<GeodataResponse>();
            addExceptionToResponseWrapper(responseWrapper, e);
            logger.error("onAjaxGetGeodataResponse", e);
		}

        return responseWrapper;
    }

    /**
     * The method to response on the "list-geodata" ajax request.
     *
     * @param  request
     *         The http servlet request.
     * @param  session
     *         The http session.
     * @param  model
     *         The model.
     *
     * @return the wrapped Geodata light models.
     */
    @RequestMapping(value=PATH_AJAX_LIST_GEODATA, method={RequestMethod.GET})
    public @ResponseBody ResponseWrapper<ArrayList<GeodataLightDTModel>> onAjaxListGeodata(HttpServletRequest request, HttpSession session, Model model) {
        ResponseWrapper<ArrayList<GeodataLightDTModel>> responseWrapper;
        try {
            //SessionUserDTModel sessionUser = SecurityContextHelper.getAuthenticatedUserDTModel();
            responseWrapper = geodataService.getLightDTModelsResponseBySessionId(session.getId());
            //responseWrapper = geodataService.getLightDTModelsResponseByUsername(sessionUser.getUsername());
        } catch(Exception e) {
            responseWrapper = new ResponseWrapper<ArrayList<GeodataLightDTModel>>();
            addExceptionToResponseWrapper(responseWrapper, e);
            logger.error("onAjaxListGeodata", e);
		}

        return responseWrapper;
    }

    /**
     * The method to response on the "get-geodata-location" ajax request.
     *
     * @param  id
     *         The Location id.
     * @param  geodataId
     *         The Geodata id.
     * @param  request
     *         The http servlet request.
     * @param  session
     *         The http session.
     * @param  model
     *         The model.
     *
     * @return the wrapped Location model.
     */
    @RequestMapping(value=PATH_AJAX_GET_GEODATA_LOCATION, method={RequestMethod.GET})
    public @ResponseBody ResponseWrapper<LocationDTModel> onAjaxGetGeodataLocation(@RequestParam(value="id", required=true) String id,
                                                                                @RequestParam(value="geodataId", required=true) String geodataId,
                                                                                HttpServletRequest request, HttpSession session, Model model) {
        ResponseWrapper<LocationDTModel> responseWrapper;
        try {
            //SessionUserDTModel sessionUser = SecurityContextHelper.getAuthenticatedUserDTModel();
            responseWrapper = geodataService.getGeodataLocationDTModelResponse(id, geodataId, session.getId());
            //responseWrapper = geodataService.getGeodataLocationDTModelResponse(id, geodataId, sessionUser.getUsername());
        } catch(Exception e) {
            responseWrapper = new ResponseWrapper<LocationDTModel>();
            addExceptionToResponseWrapper(responseWrapper, e);
            logger.error("onAjaxGetGeodataLocation", e);
		}

        return responseWrapper;
    }

    /**
     * The method to response on the "update-geodata-location" ajax request.
     *
     * @param  requestObject
     *         The request object.
     * @param  request
     *         The http servlet request.
     * @param  session
     *         The http session.
     * @param  model
     *         The model.
     *
     * @return the wrapped boolean <true> if was updated, otherwise <code>false</code>.
     */
    @RequestMapping(value=PATH_AJAX_UPDATE_GEODATA_LOCATION, method={RequestMethod.POST})
    public @ResponseBody ResponseWrapper<Boolean>
    onAjaxUpdateGeodataLocation(@RequestBody UpdateGeodataLocationRequest requestObject,
                                //@RequestParam(value="id", required=true) String id,
                                //@RequestParam(value="lat", required=true) Double lat,
                                //@RequestParam(value="lng", required=true) Double lng,
                                //@RequestParam(value="geodataId", required=true) String geodataId,
                                HttpServletRequest request, HttpSession session, Model model) {
        ResponseWrapper<Boolean> responseWrapper;
        try {
            SessionUserDTModel sessionUser = SecurityContextHelper.getAuthenticatedUserDTModel();
            responseWrapper = geodataService.updateGeodataLocation(requestObject/*id, lat, lng, geodataId*/, session.getId(), sessionUser.getUsername());
            //responseWrapper = geodataService.updateGeodataLocation(id, lat, lng, geodataId, sessionUser.getUsername());
        } catch(Exception e) {
            responseWrapper = new ResponseWrapper<Boolean>();
            addExceptionToResponseWrapper(responseWrapper, e);
            logger.error("onAjaxUpdateGeodataLocation", e);
		}

        return responseWrapper;
    }

    /**
     * The method to response on the "update-geodata-locations" ajax request.
     *
     * @param  requestObject
     *         The request object.
     * @param  request
     *         The http servlet request.
     * @param  session
     *         The http session.
     * @param  model
     *         The model.
     *
     * @return the wrapped boolean <true> if was updated, otherwise <code>false</code>.
     */
    @RequestMapping(value=PATH_AJAX_UPDATE_GEODATA_LOCATIONS, method={RequestMethod.POST})
    public @ResponseBody ResponseWrapper<Boolean>
    onAjaxUpdateGeodataLocations(@RequestBody UpdateGeodataLocationsRequest requestObject,
                                 //@RequestParam(value="locations", required=true) List<? extends LocationBean> locations,
                                 //@RequestParam(value="geodataId", required=true) String geodataId,
                                 HttpServletRequest request, HttpSession session, Model model) {
        ResponseWrapper<Boolean> responseWrapper;
        try {
            SessionUserDTModel sessionUser = SecurityContextHelper.getAuthenticatedUserDTModel();
            responseWrapper = geodataService.updateGeodataLocations(requestObject, session.getId(), sessionUser.getUsername());
            //responseWrapper = geodataService.updateGeodataLocations(requestObject, sessionUser.getUsername());
        } catch(Exception e) {
            responseWrapper = new ResponseWrapper<Boolean>();
            addExceptionToResponseWrapper(responseWrapper, e);
            logger.error("onAjaxUpdateGeodataLocations", e);
		}

        return responseWrapper;
    }

    /**
     * The method to response on the "delete-geodata-location" ajax request.
     *
     * @param  id
     *         The Location id.
     * @param  geodataId
     *         The Geodata id.
     * @param  request
     *         The http servlet request.
     * @param  session
     *         The http session.
     * @param  model
     *         The model.
     *
     * @return the wrapped boolean <true> if was deleted, otherwise <code>false</code>.
     */
    @RequestMapping(value=PATH_AJAX_DELETE_GEODATA_LOCATION, method={RequestMethod.POST})
    public @ResponseBody ResponseWrapper<Boolean> onAjaxDeleteGeodataLocation(@RequestParam(value="id", required=true) String id,
                                                                              @RequestParam(value="geodataId", required=true) String geodataId,
                                                                              HttpServletRequest request, HttpSession session, Model model) {
        ResponseWrapper<Boolean> responseWrapper;
        try {
            //SessionUserDTModel sessionUser = SecurityContextHelper.getAuthenticatedUserDTModel();
            responseWrapper = geodataService.deleteGeodataLocation(id, geodataId, session.getId());
            //responseWrapper = geodataService.deleteGeodataLocation(id, geodataId, sessionUser.getUsername());
        } catch(Exception e) {
            responseWrapper = new ResponseWrapper<Boolean>();
            addExceptionToResponseWrapper(responseWrapper, e);
            logger.error("onAjaxDeleteGeodataLocation", e);
		}

        return responseWrapper;
    }

    /**
     * The method to response on the "restore-geodata-location" ajax request.
     *
     * 2013-04-19, Don't Remove a Stop Forever
     * Allow user to 'enable' it (removed Stop) so then it reappears.
     *
     * @param  id
     *         The Location id.
     * @param  geodataId
     *         The Geodata id.
     * @param  request
     *         The http servlet request.
     * @param  session
     *         The http session.
     * @param  model
     *         The model.
     *
     * @return the wrapped boolean <true> if was restored, otherwise <code>false</code>.
     */
    @RequestMapping(value=PATH_AJAX_RESTORE_GEODATA_LOCATION, method={RequestMethod.POST})
    public @ResponseBody ResponseWrapper<Boolean> onAjaxRestoreGeodataLocation(@RequestParam(value="id", required=true) String id,
                                                                               @RequestParam(value="geodataId", required=true) String geodataId,
                                                                               HttpServletRequest request, HttpSession session, Model model) {
        ResponseWrapper<Boolean> responseWrapper;
        try {
            //SessionUserDTModel sessionUser = SecurityContextHelper.getAuthenticatedUserDTModel();
            responseWrapper = geodataService.restoreGeodataLocation(id, geodataId, session.getId());
            //responseWrapper = geodataService.restoreGeodataLocation(id, geodataId, sessionUser.getUsername());
        } catch(Exception e) {
            responseWrapper = new ResponseWrapper<Boolean>();
            addExceptionToResponseWrapper(responseWrapper, e);
            logger.error("onAjaxRestoreGeodataLocation", e);
		}

        return responseWrapper;
    }

//    /**
//     * The method to response on the "list-not-geocoded-geodata-locations" ajax request.
//     *
//     * @param  geodataId
//     *         The Geodata id.
//     * @param  request
//     *         The http servlet request.
//     * @param  session
//     *         The http session.
//     * @param  model
//     *         The model.
//     *
//     * @return the wrapped Location light models.
//     */
//    @RequestMapping(value=PATH_AJAX_LIST_NOT_GEOCODED_GEODATA_LOCATIONS, method={RequestMethod.GET})
//    public @ResponseBody ResponseWrapper<ArrayList<LocationLightBean>>
//    onAjaxListNotGeocodedGeodataLocations(@RequestParam(value="geodataId", required=true) String geodataId,
//                                          HttpServletRequest request, HttpSession session, Model model) {
//        ResponseWrapper<ArrayList<LocationLightBean>> responseWrapper;
//        try {
//            //SessionUserDTModel sessionUser = SecurityContextHelper.getAuthenticatedUserDTModel();
//            responseWrapper = geodataService.listNotGeocodedGeodataLocationLightBeans(session.getId(), geodataId);
//            //responseWrapper = geodataService.listNotGeocodedGeodataLocationLightBeans(sessionUser.getUsername(), geodataId);
//        } catch(Exception e) {
//            responseWrapper = new ResponseWrapper<ArrayList<LocationLightBean>>();
//            addExceptionToResponseWrapper(responseWrapper, e);
//            logger.error("onAjaxListGeodata", e);
//		}
//
//        return responseWrapper;
//    }

    /**
     * The method to response on the "export-geodata" ajax request.
     *
     * @param  id
     *         The geodata id.
     * @param  request
     *         The http servlet response.
     * @param  session
     *         The http session.
     * @param  model
     *         The model.
     *
     * @return The exported file bytes http entity.
     */
    @RequestMapping(value=PATH_AJAX_EXPORT_GEODATA, method={RequestMethod.GET})
    public @ResponseBody
    HttpEntity<byte[]> onAjaxExportGeodata(@RequestParam(value="id", required=true) String id,
                                           HttpServletRequest request, HttpSession session, Model model) {
        try {
            //SessionUserDTModel sessionUser = SecurityContextHelper.getAuthenticatedUserDTModel();
            return geodataService.exportGeodata(id, session.getId());
            //return geodataService.exportGeodata(id, sessionUser.getUsername());
        } catch(Exception e) {
            logger.error("onAjaxExportGeodata", e);
		}

        return null;
    }
}
